package com.example.forum.services.impl;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.dao.BoardMapper;
import com.example.forum.dao.ArticleMapper;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.Board;
import com.example.forum.services.IBoradService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class BoardServiceImpl implements IBoradService {

    @Autowired
    private BoardMapper boardMapper;

    @Autowired
    private ArticleMapper articleMapper;

    @Override
    public List<Board> selectByNum(Integer num) {
        //参数校验
        if(num<=0||num==null){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //校验通过 去查询数据
        List<Board> list=boardMapper.selectByNum(num);
        //返回结果
        return list;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        if(id<=0||id==null){
            //打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        //查询原来的板块的数量
        Board board=boardMapper.selectByPrimaryKey(id);
        if(board==null){
            //打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString()+", board id= "+id);
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //设置对象
        Board updateBoard=new Board();
        updateBoard.setId(board.getId());
        //对其进行+1
        updateBoard.setArticleCount(board.getArticleCount()+1);
        //调用执行
        int row=boardMapper.updateByPrimaryKeySelective(updateBoard);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString()+", 受影响的行数!=1");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public Board selectById(Long id) {
        if(id<=0||id==null){
            //打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        return boardMapper.selectByPrimaryKey(id);
    }

    @Override
    public void subOneArticleCountById(Long id) {
        if(id<=0||id==null){
            //打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        //查询原来的板块的数量
        Board board=boardMapper.selectByPrimaryKey(id);
        if(board==null){
            //打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString()+", board id= "+id);
            //抛出异常  统一抛出ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //设置对象
        Board updateBoard=new Board();
        updateBoard.setId(board.getId());
        //对其进行-1
        updateBoard.setArticleCount(board.getArticleCount()-1);
        //判断-1后是否为小于0 如果小于0 设置为0
        if(updateBoard.getArticleCount()<0){
            updateBoard.setArticleCount(0);
        }
        //调用执行
        int row=boardMapper.updateByPrimaryKeySelective(updateBoard);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString()+", 受影响的行数!=1");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }
    
    @Override
    public List<Board> getAllBoards() {
        return boardMapper.selectAll();
    }
    
    @Override
    public void addBoard(Board board) {
        // 参数校验
        if (board == null || board.getName() == null || board.getName().trim().isEmpty()) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 设置默认值
        board.setArticleCount(0);
        if (board.getSort() == null) {
            // 获取当前最大排序值，并+1
            Integer maxSort = boardMapper.getMaxSort();
            board.setSort(maxSort != null ? maxSort + 1 : 1);
        }
        board.setState((byte) 0); // 默认正常
        board.setDeleteState((byte) 0); // 默认未删除
        
        // 设置创建时间和更新时间
        Date now = new Date();
        board.setCreateTime(now);
        board.setUpdateTime(now);
        
        // 执行新增
        int result = boardMapper.insert(board);
        if (result != 1) {
            log.warn(ResultCode.FAILED_CREATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        
        log.info("新板块已创建: {}", board.getName());
    }
    
    @Override
    public void updateBoard(Board board) {
        // 参数校验
        if (board == null || board.getId() == null || board.getId() <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 校验板块是否存在
        Board existingBoard = boardMapper.selectByPrimaryKey(board.getId());
        if (existingBoard == null || existingBoard.getDeleteState() == 1) {
            log.warn("板块不存在或已删除: {}", board.getId());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        
        // 设置更新时间
        board.setUpdateTime(new Date());
        
        // 执行更新
        int result = boardMapper.updateByPrimaryKeySelective(board);
        if (result != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 板块更新失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
        
        log.info("板块已更新: {}", board.getId());
    }
    
    @Override
    public void updateBoardState(Long boardId, Byte state) {
        // 参数校验
        if (boardId == null || boardId <= 0 || (state != 0 && state != 1)) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 校验板块是否存在
        Board existingBoard = boardMapper.selectByPrimaryKey(boardId);
        if (existingBoard == null || existingBoard.getDeleteState() == 1) {
            log.warn("板块不存在或已删除: {}", boardId);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        
        // 创建更新对象
        Board updateBoard = new Board();
        updateBoard.setId(boardId);
        updateBoard.setState(state);
        updateBoard.setUpdateTime(new Date());
        
        // 执行更新
        int result = boardMapper.updateByPrimaryKeySelective(updateBoard);
        if (result != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 板块状态更新失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
        
        log.info("板块状态已更新: boardId={}, state={}", boardId, state);
    }
    
    @Override
    public void deleteBoard(Long boardId) {
        // 参数校验
        if (boardId == null || boardId <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 校验板块是否存在
        Board existingBoard = boardMapper.selectByPrimaryKey(boardId);
        if (existingBoard == null) {
            log.warn("板块不存在: {}", boardId);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        
        // 如果该板块有文章，不允许删除
        if (existingBoard.getArticleCount() > 0) {
            log.warn("板块下存在文章，无法删除: boardId={}, articleCount={}", boardId, existingBoard.getArticleCount());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED, "该板块下存在文章，无法删除"));
        }
        
        // 创建更新对象（逻辑删除）
        Board updateBoard = new Board();
        updateBoard.setId(boardId);
        updateBoard.setDeleteState((byte) 1);
        updateBoard.setUpdateTime(new Date());
        
        // 执行更新
        int result = boardMapper.updateByPrimaryKeySelective(updateBoard);
        if (result != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 板块删除失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
        
        log.info("板块已删除（逻辑删除）: {}", boardId);
    }
    
    @Override
    public void updateBoardSort(Long boardId, Integer sort) {
        // 参数校验
        if (boardId == null || boardId <= 0 || sort == null || sort < 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 校验板块是否存在
        Board existingBoard = boardMapper.selectByPrimaryKey(boardId);
        if (existingBoard == null || existingBoard.getDeleteState() == 1) {
            log.warn("板块不存在或已删除: {}", boardId);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        
        // 创建更新对象
        Board updateBoard = new Board();
        updateBoard.setId(boardId);
        updateBoard.setSort(sort);
        updateBoard.setUpdateTime(new Date());
        
        // 执行更新
        int result = boardMapper.updateByPrimaryKeySelective(updateBoard);
        if (result != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 板块排序更新失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
        
        log.info("板块排序已更新: boardId={}, sort={}", boardId, sort);
    }

    @Override
    public int fixArticleCount(Long boardId) {
        if(boardId == null || boardId <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 查询板块是否存在
        Board board = boardMapper.selectByPrimaryKey(boardId);
        if(board == null) {
            log.warn(ResultCode.ERROR_IS_NULL.toString() + ", board id= " + boardId);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        
        // 计算实际文章数
        int actualCount = articleMapper.countArticlesByBoardId(boardId);
        
        // 如果与当前存储的值不同，则更新
        if (board.getArticleCount() == null || board.getArticleCount() != actualCount) {
            Board updateBoard = new Board();
            updateBoard.setId(boardId);
            updateBoard.setArticleCount(actualCount);
            int row = boardMapper.updateByPrimaryKeySelective(updateBoard);
            
            if (row != 1) {
                log.warn(ResultCode.FAILED.toString() + ", 受影响的行数!=1");
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
            }
        }
        
        log.info("板块文章计数修复成功: boardId={}, 原值={}, 新值={}", 
                 boardId, board.getArticleCount(), actualCount);
        
        return actualCount;
    }

    @Override
    public int getActualArticleCount(Long boardId) {
        if(boardId == null || boardId <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        
        // 调用数据访问层获取实际文章数量
        return boardMapper.getActualArticleCount(boardId);
    }
}
